home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / SHELLS / TPSHELL / SHELL.PAS < prev    next >
Pascal/Delphi Source File  |  1986-05-23  |  4KB  |  125 lines

  1. {$V-}
  2.   { This procedure allows a Turbo Pascal program to execute any DOS
  3.     command string. COMMAND.COM does the work of looking for command extentions,
  4.     (.COM, .EXE, or .BAT), internal commands, piping, redirection, etc.
  5.  
  6.     Commands can be .BAT files, DOS commands or any other compiled programs,
  7.     but the DOS SET, PROMPT, and PATH commands cannot be used.
  8.  
  9.     Written by:
  10.         Bill Mayne
  11.         9707 Lawndale Dr.
  12.         Silver Spring, MD  20901
  13.  
  14.     Based on work by:
  15.         Bela Lubkin
  16.         Borland International Technical Support
  17.  
  18.     This version differs from Lubkin's in that:
  19.  
  20.     (1) It always uses COMMAND.COM. Consequently, the code is a bit simpler
  21.     and it is easier to use, though not quite as efficient in some cases.
  22.     It does not allow you to over-ride or by-pass the normal path search.
  23.     (In exceptional cases that might be disadvantage, normally it is what you
  24.     want.) The both the source and object code are somewhat smaller.
  25.  
  26.     (2) The FCBs passed to the subprocess contain blanks for the filename.ext
  27.     rather than the name of the command. (It works anyway. I don't know the
  28.     purpose of these FCBs. It shortens the code some to do it this way.)
  29.  
  30.     (3) The search of the pathname of COMMAND.COM in the environment string is not
  31.     simplified, saving some storage.
  32.  
  33.     (4) It is changed to a procedure instead of a function, but it would be
  34.     easy to change it back if you prefer a function.
  35.  
  36.     The value returned in RC is the value returned by DOS after the DOS call.
  37.     See a DOS technical reference manual for more information on it.
  38.     Suffice it to say that anything nonzero means something went wrong.
  39.  
  40.     VERY IMPORTANT NOTE: you MUST use the Options menu of Turbo Pascal to
  41.     restrict the amount of free dynamic memory used by your program.  Only the
  42.     memory that is not used by the heap is available for use by other programs.
  43.     A very simple program needs about $40 paragraphs (1K bytes). A minimum of
  44.     $100 (4K) is suggested. Some programs may obviously need more. }
  45.  
  46. type
  47.   ShellStr=string[127];
  48. { This is the only definition (except the procedure itself) known to
  49.   the outside program, and the only one needed by the procedure.
  50.   This level of independence is desirable for "toolbox" include files
  51.   which may be used in many different programs. }
  52.  
  53. procedure Shell(CommandLine: ShellStr;var rc:integer);
  54.  
  55.   Type
  56.     Env=Array [0..32767] Of Char;
  57.   Var
  58.     EPtr: ^Env;
  59.     I: Integer;
  60.     Regs: Record Case Integer Of
  61.             1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
  62.             2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
  63.           End;
  64.     FCB1,FCB2: Array [0..36] Of Byte;
  65.     PathName: String[66];
  66.     CommandTail: String[135];
  67.     ParmTable: Record
  68.                  EnvSeg: Integer;
  69.                  ComLin: ^Integer;
  70.                  FCB1Pr: ^Integer;
  71.                  FCB2Pr: ^Integer;
  72.                End;
  73.   Begin
  74.   PathName:=PathName+#0;
  75.  
  76.     With Regs Do
  77.      Begin
  78.       {Create FCBs for EXEC call}
  79.       FillChar(FCB1,Sizeof(FCB1),0);
  80.       FillChar(FCB1[2],11,ord(' ')); {blank filename.ext}
  81.       FillChar(FCB2,Sizeof(FCB2),0);
  82.       FillChar(FCB2[2],11,ord(' ')); {blank filename.ext}
  83. (* May  not need this -
  84.       {Deallocate unused memory}
  85.       ES:=CSeg;
  86.       BX:=SSeg-CSeg+MemW[CSeg:MemW[CSeg:$0101]+$112];
  87.       AH:=$4A;
  88.       MsDos(Regs);
  89. *)
  90.     {Scan the env and set DS:DX ==> pathname of COMMAND.COM}
  91.     DS:=MemW[CSeg:$002C];
  92.     DX:=0;
  93.     PathName[0]:=chr(8);
  94.     move(Mem[DS:0],PathName[1],8);
  95.     while PathName<>'COMSPEC=' do
  96.       begin
  97.         repeat
  98.           DX:=DX+1;
  99.         until Mem[DS:DX]=0;
  100.         DX:=DX+1;
  101.         move(Mem[DS:DX],Pathname[1],8);
  102.       end;
  103.       DX:=DX+8;
  104.  
  105.       {Now comes the EXEC (DOS function $4B) call}
  106.       CommandTail:=' /C '+CommandLine+^M;
  107.       CommandTail[0]:=Pred(CommandTail[0]);
  108.       With ParmTable Do
  109.        Begin
  110.         EnvSeg:=MemW[CSeg:$002C];
  111.         ComLin:=Addr(CommandTail);
  112.         FCB1Pr:=Addr(FCB1);
  113.         FCB2Pr:=Addr(FCB2);
  114.        End;
  115.       ES:=Seg(ParmTable);
  116.       BX:=Ofs(ParmTable);
  117.       AX:=$4B00;
  118.       MsDos(Regs); { Call subprocess }
  119.  
  120.       {Pass the return code back to the caller}
  121.       If (Flags And 1)<>0 Then rc:=AX
  122.       Else rc:=0;
  123.      End;
  124.   End;
  125.